﻿using System;

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Xml;
using System.IO;
using Microsoft.WindowsMobile.PocketOutlook;
using uk.org.aspellclark.todolistppc.Tasks;

namespace uk.org.aspellclark.todolistppc
{
    public partial class frmMain : Form
    {
        #region Variables
        private List<CTask> lstAllTasks = new List<CTask>();

        private const string M_NEW_TASK_NAME = "New Task";
        XmlDocument xmlDoc;
        private PreferencesXml oPreferences;
        private TreeNode m_SelectedTreeNode = null;
        private bool m_bEncrypt = false;
        private bool m_bStarting = false;
        private string m_strFile = "TodoList.xml";
        private int m_iLevel;
        private CTask m_selectedTask;
        private bool m_bLoadingData = false;
        private bool m_bDataChanged = false;
        private bool m_bNodeDataChanged = false;


        private string m_sFileFormat = "6";
        private string m_sProjectName = null;
        private Int16 m_iNextUniqueID = -1;
        private string m_sFileVersion = "1";
        private string m_sLastModified = null;
        private string m_sLastSortBy = null;
        private string m_sLastSortDir = null;
        private DateTime m_dtEarliestDueDate;

        private System.Drawing.Font m_Font;
        private string m_sCurrFontSize = "VSmall";
        private Hashtable m_htFontSizes = new Hashtable();

        private TreeNode ClipboardTreeNode;
        #endregion

        #region Properties
        private bool DataChanged
        {
            get { return m_bDataChanged; }
            set { m_bDataChanged = value; }
        }
        private bool LoadingData
        {
            get { return m_bLoadingData; }
            set { m_bLoadingData = value; }
        }
        #endregion

        public frmMain()
        {
            oPreferences = new PreferencesXml();
            m_bStarting = true;
            InitializeComponent();
            ApplyPreferences();
            LoadLastFile();
        }

        private void MainForm_Resize(object sender, System.EventArgs e)
        {
            if (Screen.PrimaryScreen.Bounds.Width > Screen.PrimaryScreen.Bounds.Height)
            {
                Landscape();
            }
            else
            {
                Portrait();
            }
        }

        private void ApplyPreferences()
        {
            oPreferences = new PreferencesXml();
            LoadPreferences();
            #region Font
            int iFontSize;
            try
            {
                iFontSize = Convert.ToInt16(oPreferences.getPreference("FontSize"));
            }
            catch(Exception)
            {
                iFontSize = 12;
            }
            m_Font = new Font("Tahoma", iFontSize , FontStyle.Regular);
            oTVTodoList.Font = m_Font;
            #endregion
            #region ButtonMenu
            try
            {
                bool bButtonMenu;
                bButtonMenu = Convert.ToBoolean(oPreferences.getPreference("ButtonMenuEnabled"));
                if (bButtonMenu)
                {
                    m_mnuMain.MenuItems.Clear();
                    m_mnuMain.Dispose();
                    bMenu.Visible = true;
                }
                else
                {
                    DisablebMenu();
                    m_mnuMain = new System.Windows.Forms.MainMenu();
                    m_mnuMain.MenuItems.Add(this.mnuTools);
                    m_mnuMain.MenuItems.Add(this.menuItem2);
                    m_mnuMain.MenuItems.Add(this.menuItem3);
                    m_mnuMain.MenuItems.Add(this.menuItem4);
                    Menu = m_mnuMain;
                }
            }
            catch (Exception)
            {
                bMenu.Visible = false;
            }
            #endregion
#region XMLDOM
            try
            {
                if(Convert.ToBoolean(oPreferences.getPreference("XMLDOM")))
                {
                    SetFilter(0);
                    
                }
            }
            catch (Exception)
            {

            }
#endregion

        }

        private void LoadLastFile()
        {
            String oldFileName = oPreferences.getPreference("LastOpenedFile");
            if (oldFileName == null | oldFileName == "" || oldFileName.Length == 0)
            {
                //no last file name stored
            }
            else
            {
                if (File.Exists(oldFileName))
                {
                    m_strFile = oldFileName;
                    InitialiseTree();
                    LoadingData = false;
                }
            }
        }

        private void InitialiseTree()
        {
            try
            {
                if (Convert.ToBoolean(oPreferences.getPreference("XMLDOM")))
                {
                    SetFilter(0);

                }
                else
                {
                    FillTree();
                }
            }
            catch (Exception)
            {
                FillTree();
            }
            
        }

        #region Menu Callbacks
        #region Tools
        private void mnuToolsOpen_Click(object sender, EventArgs e)
        {
            OpenFile();
        }
        private void mnuToolsClose_Click(object sender, EventArgs e)
        {
            NewFile();
        }
        private void mnuToolsSave_Click(object sender, EventArgs e)
        {
            SaveFile();
        }
        private void mnuToolsSaveAs_Click(object sender, EventArgs e)
        {
            DataChanged = true;
            SaveAs();
        }
        private void Preferences_Click(object sender, EventArgs e)
        {
            FrmPreferences ofrmPreferences = new FrmPreferences();
            ofrmPreferences.Closed += new EventHandler(PreferencesClosed);
            ofrmPreferences.ShowDialog();

            //FrmSettings ofrmsettings = new FrmSettings();
            //ofrmsettings.Closed += new EventHandler(SettingsClosed);
            //ofrmsettings.ShowDialog();
            
        }
        private void SettingsClosed(object o, EventArgs e)
        {
            ApplyPreferences();
        }
        private void PreferencesClosed(object o, EventArgs e)
        {
            ApplyPreferences();
        }
        private void mnuToolsExit_Click(object sender, EventArgs e)
        {
            Close();
        }
        #endregion
        private void mnuHelpAbout_Click(object sender, EventArgs e)
        {
            using (FrmAboutBox frmObj = new FrmAboutBox())
            {
                frmObj.AppTitle = "ToDoListPPC";
                frmObj.AppDescription = "Pocket PC Todolist";
                string sTmpText = this.Text;
                this.Text = "";
                frmObj.Text = sTmpText;
                frmObj.ShowDialog();
                this.Text = sTmpText;
                frmObj.Dispose();
            }
        }
        #region View
        private void mnuViewAll_Click(object sender, EventArgs e)
        {
            SetViewFilter(0);
        }
        private void mnuViewActive_Click(object sender, EventArgs e)
        {
            SetViewFilter(1);
        }
        private void mnuViewComplete_Click(object sender, EventArgs e)
        {
            SetViewFilter(2);
        }
        private void mnuViewRefresh_Click(object sender, EventArgs e)
        {
            FillTree();
        }
        #endregion
        private void mnuNewTask_Click(object sender, EventArgs e)
        {
            AddTask();
        }
        private void mnuNewSubTask_Click(object sender, EventArgs e)
        {
            AddSubTask();
        }
        private void mnuDeleteTask_Click(object sender, EventArgs e)
        {
            DeleteTask();
        }
        private void menuItem9_Click(object sender, EventArgs e)
        {
            CopyNode();
        }
        private void menuItem12_Click(object sender, EventArgs e)
        {
            CopyNode();
            m_SelectedTreeNode.Remove();
        }

        private void CopyNode()
        {
            if (m_SelectedTreeNode != null)
            {
                ClipboardTreeNode = m_SelectedTreeNode;
            }
        }

        private void menuItem10_Click(object sender, EventArgs e)
        {
            TreeNode ClipboardNode = ClipboardTreeNode;
            if (m_SelectedTreeNode == null)
            {
                oTVTodoList.Nodes.Add(ClipboardNode);

            }
            else if (m_SelectedTreeNode.Parent == null)
            {
                oTVTodoList.Nodes.Insert(m_SelectedTreeNode.Index + 1, ClipboardNode);
            }
            else
            {
                m_SelectedTreeNode.Parent.Nodes.Insert(m_SelectedTreeNode.Index + 1,ClipboardNode);
            }
        }
        private void menuItem14_Click(object sender, EventArgs e)
        {
            TreeNode ClipboardNode = ClipboardTreeNode;
            if (m_SelectedTreeNode != null)
            {
                m_SelectedTreeNode.Nodes.Insert(m_SelectedTreeNode.Index + 1,ClipboardNode);
            }
        }
        #endregion

        #region Widget Callbacks

        private void m_tvTodoList_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node.Tag != null)
            {
                m_SelectedTreeNode = e.Node;
            }
            else
            {
                m_SelectedTreeNode = e.Node;
                TodoListTreeNode tlNode = (TodoListTreeNode)e.Node;
                if (tlNode.Task != null)
                {
                m_selectedTask = tlNode.Task;

                if (m_selectedTask.Priority > 0)
                {
                    m_tbxPriority.Text = m_selectedTask.Priority.ToString();
                }
                else
                {
                    m_tbxPriority.Text = "";
                }

                if (m_selectedTask.HoursEst > 0)
                {
                    txtTimeEstimate.Text = m_selectedTask.HoursEst.ToString();
                }
                else
                {
                    txtTimeEstimate.Text = "";
                }

                if (m_selectedTask.PercentComplete > 0)
                {
                    m_tbxPercentComplete.Text = m_selectedTask.PercentComplete.ToString();
                }
                else
                {
                    m_tbxPercentComplete.Text = "";
                }
                m_selectedTask.Title = tlNode.Text;
                txtTitle.Text = m_selectedTask.Title;
                txtAllocatedTo.Text = m_selectedTask.AllocatedTo;
                chkOutlookAppointmentEnabled.Checked = m_selectedTask.OutlookAppointmentEnabled;
                m_tbxStartDate.Text = m_selectedTask.StartDateStr;
                m_tbxDueDate.Text = m_selectedTask.DueDateStr;
                m_tbxCompletedDate.Text = m_selectedTask.DoneDateStr;
                if (m_selectedTask.StartDate != new DateTime())
                { 
                    dtpStartDate.Value = m_selectedTask.StartDate;
                }
                if (m_selectedTask.DueDate != new DateTime())
                {
                    dtpDueDate.Value = m_selectedTask.DueDate;
                }
                if (m_selectedTask.DoneDate != new DateTime())
                {
                    dtpCompletedDate.Value = m_selectedTask.DoneDate;
                }

                txtNotes.Text = m_selectedTask.CommentsStr;
                txtTaskName.Visible = true;
                txtTaskName.Text = m_SelectedTreeNode.Text;

                try
                {
                    dtDueDate.Value = DateTime.Parse(tlNode.Task.DueDate.ToString());
                    dtDueDate.Visible = true;
                }
                catch (Exception)
                {

                }
            }
            else
            {
                txtTaskName.Visible = false;
                txtTaskName.Text = string.Empty;
                dtDueDate.Visible = false;
            }
 
            }

        }

        private void m_tvTodoList_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (e.Node.Tag != null)
            {
                m_SelectedTreeNode = e.Node;
            }
            else
            {
                TodoListTreeNode tlNode = e.Node as TodoListTreeNode;
                tlNode.Clicked(tlNode.Checked);

                TodoListTreeNode selectedNode = oTVTodoList.SelectedNode as TodoListTreeNode;
                if ((selectedNode != null) && (selectedNode.TaskId == tlNode.TaskId))
                {
                    if (tlNode.Task.PercentComplete > 0)
                    {
                        m_tbxPercentComplete.Text = tlNode.Task.PercentComplete.ToString();
                    }
                    else
                    {
                        m_tbxPercentComplete.Text = "";
                    }
                }

                DataChanged = true;
            }
        }

        private void txtTitle_TextChanged(object sender, EventArgs e)
        {
            TodoListTreeNode selectedNode = oTVTodoList.SelectedNode as TodoListTreeNode;
            CTask tmpTask = selectedNode.Task;
            tmpTask.Title = txtTitle.Text;
            selectedNode.Text = tmpTask.Title;
            DataChanged = true;
        }

        private void txtTitle_GotFocus(object sender, EventArgs e)
        {

        }

        private void txtAllocatedTo_TextChanged(object sender, EventArgs e)
        {

        }

        private void m_tbxPercentComplete_TextChanged(object sender, EventArgs e)
        {
            TodoListTreeNode selectedNode = oTVTodoList.SelectedNode as TodoListTreeNode;
            CTask tmpTask = selectedNode.Task;
            try { tmpTask.PercentComplete = Convert.ToInt16(m_tbxPercentComplete.Text); }
            catch { }
            if (tmpTask.Complete) { selectedNode.ImageIndex = 1; selectedNode.SelectedImageIndex = 1; }
            DataChanged = true;
        }

        private void m_tbxCompletedDate_TextChanged(object sender, EventArgs e)
        {
            TodoListTreeNode selectedNode = oTVTodoList.SelectedNode as TodoListTreeNode;
            CTask tmpTask = selectedNode.Task;
            //try { tmpTask.DoneDate = new DateTime(m_tbxCompletedDate.Text); } catch {}
            DataChanged = true;
        }

        private void m_tbxDueDate_TextChanged(object sender, EventArgs e)
        {

        }

        private void m_tbxStartDate_TextChanged(object sender, EventArgs e)
        {

        }

        private void txtNotes_TextChanged(object sender, EventArgs e)
        {
            TodoListTreeNode selectedNode = oTVTodoList.SelectedNode as TodoListTreeNode;
            CTask tmpTask = selectedNode.Task;
            tmpTask.CommentsStr = txtNotes.Text;
            DataChanged = true;
        }

        private void m_cmbSortBy_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void m_cmbSortDirection_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void m_tbxProjectName_TextChanged(object sender, EventArgs e)
        {
            m_sProjectName = m_tbxProjectName.Text;
            m_lblProject.Text = m_sProjectName;
            if (!LoadingData)
            {
                DataChanged = true;
            }
        }

        private void txtTaskName_TextChanged(object sender, EventArgs e)
        {
            if(oTVTodoList.SelectedNode != null)
            {
                TodoListTreeNode selectedNode = oTVTodoList.SelectedNode as TodoListTreeNode;
                CTask tmpTask = selectedNode.Task;
                tmpTask.Title = txtTaskName.Text;
                m_SelectedTreeNode.Text = txtTaskName.Text;
                txtTitle.Text = txtTaskName.Text;
                DataChanged = true;
            }
        }

        private void txtTaskName_LostFocus(object sender, EventArgs e)
        {
            if(!dtDueDate.Focused)
            {
                txtTaskName.Visible = false;
                dtDueDate.Visible = false;
            }
        }

        private void dtDueDate_ValueChanged(object sender, EventArgs e)
        {
            if (m_SelectedTreeNode != null)
            {
                TodoListTreeNode tlNode = m_SelectedTreeNode as TodoListTreeNode;
                tlNode.Task.DueDate = dtDueDate.Value;
            }
        }

        private void dtDueDate_LostFocus(object sender, EventArgs e)
        {
            if (!txtTaskName.Focused)
            {
                txtTaskName.Visible = false;
                dtDueDate.Visible = false;
            }
        }

        #region Details Tab
        //TODO: Load Priority bar
        private void tbPriority_ValueChanged(object sender, EventArgs e)
        {
            TodoListTreeNode selectedNode = oTVTodoList.SelectedNode as TodoListTreeNode;
            CTask tmpTask = selectedNode.Task;
            try
            {
                tmpTask.Priority = Convert.ToInt16(tbPriority.Value);
            }
            catch
            {
                //MF: 28/06/2009
                //TODO:implement warning or log for catch
            }
            m_tbxPriority.Text = tbPriority.Value.ToString();
            DataChanged = true;
        }

        private void m_tbxPriority_TextChanged(object sender, EventArgs e)
        {
            TodoListTreeNode selectedNode = oTVTodoList.SelectedNode as TodoListTreeNode;
            CTask tmpTask = selectedNode.Task;
            try
            {
                tmpTask.Priority = Convert.ToInt16(m_tbxPriority.Text);
            }
            catch 
            {
                //MF: 28/06/2009
                //TODO:implement warning or log for catch
            }
            tbPriority.Value = Convert.ToInt16(m_tbxPriority.Text);
            DataChanged = true;
        }
        #endregion

        #endregion

        #region Preferences
        private void SetPref(string psName, string psValue)
        {
            oPreferences.setPreference(psName, psValue);
            SavePreferences();
        }
        private string GetPref(string psName)
        {
            return oPreferences.getPreference(psName);
        }
        private void SavePreferences()
        {
            oPreferences.writeToFile();
        }
        private void LoadPreferences()
        {
            oPreferences.readFromFile();
        }
        #endregion

        private void frmMain2_Closing(object sender, CancelEventArgs e)
        {
            DialogResult saveChanges = DialogResult.Yes;
            if (DataChanged)
            {
                //ask to lose changes???
                saveChanges = MessageBox.Show("Save Changes you have made to this todo list?", "Save Changes?", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
            }
            else
            {
                saveChanges = DialogResult.No;
            }

            if (saveChanges == DialogResult.Yes)
            {
                if (m_strFile == "")
                {
                    SaveAs();
                }
                else
                {
                    writeTodoListFile();
                }
            }
        }

        private void SaveAs()
        {
            SaveFileDialog sfdTodoList = new SaveFileDialog();

            sfdTodoList.Filter = "Todolist file (*.tdl)|*.tdl|All files (*.*)|*.*";
            sfdTodoList.FilterIndex = 1;
            sfdTodoList.FileName = m_strFile;

            if (sfdTodoList.ShowDialog() == DialogResult.OK)
            {
                m_strFile = sfdTodoList.FileName;
                m_sProjectName = m_strFile;
                writeTodoListFile();
            }
        }

        private void writeTodoListFile()
        {
            if (m_strFile == "")
            {
                m_strFile = "TodoList.xml";
            }
            if (DataChanged == true)
            {
                if (File.Exists(m_strFile))
                {
                    if (File.Exists(m_strFile + ".bak"))
                    {
                        File.Delete(m_strFile + ".bak");
                    }
                    File.Move(m_strFile, m_strFile + ".bak");
                }
                XmlTextWriter xmlWriter = new XmlTextWriter(m_strFile, System.Text.Encoding.GetEncoding("Windows-1252"));

                xmlWriter.Formatting = Formatting.Indented;
                xmlWriter.Indentation = 0;
                xmlWriter.IndentChar = ' ';

                xmlWriter.WriteStartDocument();

                if (m_bEncrypt)
                {
                    //writeOutEncryptedFile();
                }
                else
                {
                    //write out the root element - Project
                    xmlWriter.WriteStartElement("TODOLIST");

                    xmlWriter.WriteAttributeString("", "FILEFORMAT", "", m_sFileFormat);
                    xmlWriter.WriteAttributeString("", "PROJECTNAME", "", m_sProjectName);
                    xmlWriter.WriteAttributeString("", "NEXTUNIQUEID", "", m_iNextUniqueID.ToString());
                    xmlWriter.WriteAttributeString("", "EARLIESTDUEDATE", "", CommonFunctions.DateTimeToOleDate(m_dtEarliestDueDate).ToString());

                    int iFileVer = Convert.ToInt32(m_sFileVersion);
                    iFileVer++;
                    m_sFileVersion = iFileVer.ToString();
                    xmlWriter.WriteAttributeString("", "FILEVERSION", "", m_sFileVersion);

                    m_sLastModified = DateTime.Now.ToString("yyyy-mm-dd");
                    xmlWriter.WriteAttributeString("", "LASTMODIFIED", "", m_sLastModified);


                    //write out the tree nodes

                    foreach (TodoListTreeNode tmpNode in oTVTodoList.Nodes)
                    {
                        OutputNodes(xmlWriter, tmpNode);
                    }

                    xmlWriter.WriteEndElement();
                    xmlWriter.WriteEndDocument();
                    xmlWriter.Flush();
                    xmlWriter.Close();
                    DataChanged = false;

                    m_lblProject.Text = m_sProjectName + " [v" + m_sFileVersion + " - " + m_sLastModified + "]";
                }//if (m_bEncrypt)
            }//if (DataChanged)
        }

        private void OutputNodes(XmlTextWriter pXmlWriter, TodoListTreeNode pNode)
        {
            CTask currTask = pNode.Task;
            if(currTask.OutlookAppointmentEnabled)
            {
                 OutlookSession oOutlookSession = new OutlookSession();
                if (string.IsNullOrEmpty(currTask.OutlookAppointmentID))
                {
                    OutlookSession AppSession = new OutlookSession();
                    Appointment oAppointment = AppSession.Appointments.Items.AddNew();
                    pi_UpdateOutlookAppointment(oAppointment, currTask);
                    currTask.OutlookAppointmentID = oAppointment.ItemId.ToString();
                }
                else
                {
                    ItemId oExistingItemID = new ItemId(Convert.ToInt32(currTask.OutlookAppointmentID));
                    Appointment oExistingAppointment = new Appointment(oExistingItemID);
                    pi_UpdateOutlookAppointment(oExistingAppointment, currTask);
                }
            }
            else
            {
                //TODO: Delete appointment from outlook
            }
            
            currTask.writeToXml(pXmlWriter);
            foreach (TodoListTreeNode tmpNode in pNode.Nodes)
            {
                OutputNodes(pXmlWriter, tmpNode);
            }
            currTask.endWriteToXml(pXmlWriter);
        }

        private void SetViewFilter(Int16 iLevel)
        {
            mnuViewAll.Checked = false;
            mnuViewActive.Checked = false;
            mnuViewComplete.Checked = false;

            if (iLevel == 0)
            {
                mnuViewAll.Checked = true;
            }
            else if (iLevel == 1)
            {
                mnuViewActive.Checked = true;
            }
            else if (iLevel == 2)
            {
                mnuViewComplete.Checked = true;
            }

            m_iLevel = iLevel;

            FillTree();
        }

        private void FillTree()
        {
            bool failtoopen = false;
            Cursor.Current = Cursors.WaitCursor;
            DialogResult loseChanges = DialogResult.No;
            if (DataChanged)
            {
                //ask to lose changes???
                loseChanges = MessageBox.Show("Lose Changes you have made to this todo list?", "Lose Changes?", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
            }
            else
            {
                loseChanges = DialogResult.Yes;
            }

            if (loseChanges == DialogResult.Yes)
            {
                XmlDocument xmlTodoList;
                XmlNode xndList;
                TodoListTreeNode tnParent;

                try
                {
                    xmlTodoList = new XmlDocument();

                    xmlTodoList.Load(m_strFile);

                    oTVTodoList.BeginUpdate();

                    oTVTodoList.Nodes.Clear();

                    if (xmlTodoList.GetElementsByTagName("TODOLIST").Count > 0)
                    {
                        xndList = xmlTodoList.GetElementsByTagName("TODOLIST").Item(0);
                        m_sProjectName = xndList.Attributes.GetNamedItem("PROJECTNAME").InnerText;
                        m_tbxProjectName.Text = m_sProjectName;
                        m_sFileFormat = xndList.Attributes.GetNamedItem("FILEFORMAT").InnerText;
                        m_iNextUniqueID = Convert.ToInt16(xndList.Attributes.GetNamedItem("NEXTUNIQUEID").InnerText);
                        try { m_dtEarliestDueDate = CommonFunctions.OleDateToDateTime(Convert.ToDouble(xndList.Attributes.GetNamedItem("EARLIESTDUEDATE").InnerText)); }
                        catch { }
                        try { m_sLastSortBy = xndList.Attributes.GetNamedItem("LASTSORTBY").InnerText; }
                        catch { }
                        try { m_sFileVersion = xndList.Attributes.GetNamedItem("FILEVERSION").InnerText; }
                        catch { }
                        try { m_sLastSortDir = xndList.Attributes.GetNamedItem("LASTSORTDIR").InnerText; }
                        catch { }
                        try { m_sLastModified = xndList.Attributes.GetNamedItem("LASTMODIFIED").InnerText; }
                        catch { }

                        m_lblProject.Text = m_sProjectName + " [v" + m_sFileVersion + "]";

                        if (xndList.HasChildNodes == true)
                        {
                            for (int i = 0; i < xndList.ChildNodes.Count; i++)
                            {
                                AppendTask(null, xndList.ChildNodes.Item(i));
                            }
                        }
                    }

                    oTVTodoList.Font = m_Font;
                    oTVTodoList.EndUpdate();
                }
                catch (Exception e)
                {
                    MessageBox.Show("Invalid Todo List File");
                    failtoopen = true;
                    //tnParent = new TodoListTreeNode("Invalid Todo List File");
                    //tnParent.Task = new CTask();
                    //tnParent.ImageIndex = 4;
                    //tnParent.SelectedImageIndex = 4;
                    //oTVTodoList.Nodes.Add(tnParent);
                    //tnParent.Expand();
                }
            }
            if (!failtoopen)
            {
                foreach (TodoListTreeNode childNode in oTVTodoList.Nodes)
                {
                    SetChecked(childNode);
                }
            }
            Cursor.Current = Cursors.Default;
        }

        private void SetChecked(TodoListTreeNode pNode)
        {
            if (pNode.Nodes.Count > 0)
            {
                foreach (TodoListTreeNode childNode in pNode.Nodes)
                {
                    SetChecked(childNode);
                }
            }
            CTask clsTask = pNode.Task;
            pNode.Checked = clsTask.Complete;
        }

        private void AppendTask(TodoListTreeNode tnParent, XmlNode xndTask)
        {
            TodoListTreeNode tnChild;
            CTask clsTask;

            if (xndTask.Name.ToUpper() == "TASK")
            {
                clsTask = new CTask();
                clsTask.readFromXml(xndTask);

                tnChild = new TodoListTreeNode(clsTask.Title);
                tnChild.TaskId = clsTask.TaskId;
                tnChild.Task = clsTask;
                //tnChild.BackColor = Color.FromArgb((int)clsTask.PriorityColour);
                if (tnParent != null)
                {
                    
                    tnChild.ParentTaskId = tnParent.TaskId;
                }

                if (xndTask.HasChildNodes == true)
                {
                    for (int i = 0; i < xndTask.ChildNodes.Count; i++)
                    {
                        AppendTask(tnChild, xndTask.ChildNodes.Item(i));
                    }
                }
                tnChild.Checked = clsTask.Complete;

                if ((m_iLevel == 0) || ((m_iLevel == 1) && (clsTask.Complete == false)) || ((m_iLevel == 1) && (clsTask.Complete == true) && (tnChild.GetNodeCount(false) > 0)) || ((m_iLevel == 2) && (clsTask.Complete == true)) || ((m_iLevel == 2) && (clsTask.Complete == false) && (tnChild.GetNodeCount(false) > 0)))
                {
                    if (tnParent == null)
                    {
                        oTVTodoList.Nodes.Add(tnChild);
                    }
                    else
                    {
                        tnParent.Nodes.Add(tnChild);
                    }
                }
                lstAllTasks.Add(clsTask);
            }
            else if (xndTask.Name.ToUpper() == "COMMENTS")
            {
                if (tnParent != null)
                {
                    clsTask = tnParent.Task;
                    clsTask.CommentsStr = xndTask.InnerText;
                    tnParent.Task = clsTask;
                }
            }
            
        }

        private void pi_clearData()
        {
            oTVTodoList.Nodes.Clear();
            txtTaskName.Visible = false;
            txtTaskName.Text = "";
            dtDueDate.Visible = false;
        }

        private void pi_UpdateOutlookAppointment(Appointment oAppointment, CTask oTask)
        {

            oAppointment.Subject = oTask.Title;
            oAppointment.Start = DateTime.Now;
            oAppointment.End = DateTime.Now.AddHours(3);

            oAppointment.Update();
        }

        private void chkOutlookAppointmentEnabled_CheckStateChanged(object sender, EventArgs e)
        {
            TodoListTreeNode selectedNode = oTVTodoList.SelectedNode as TodoListTreeNode;
            CTask tmpTask = selectedNode.Task;
            tmpTask.OutlookAppointmentEnabled = chkOutlookAppointmentEnabled.Checked;
            DataChanged = true;
        }
        #region Methods
        #region File
        private void SaveFile()
        {
            if (m_strFile == "")
            {
                SaveAs();
            }
            else
            {
                writeTodoListFile();
            }
        }
        private void NewFile()
        {
            DialogResult saveChanges = MessageBox.Show("Save Changes you have made to this todo list?", "Save Changes?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
            if (saveChanges == DialogResult.Yes)
            {
                if (m_strFile == "")
                {
                    SaveAs();
                }
                else
                {
                    writeTodoListFile();
                }
            }
            if(saveChanges != DialogResult.Cancel)
            {
                pi_clearData();
            }
        }
        private void OpenFile()
        {
            DialogResult saveChanges = DialogResult.Yes;
            if (DataChanged)
            {
                //ask to lose changes???
                saveChanges = MessageBox.Show("Save Changes you have made to this todo list?", "Save Changes?", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
            }
            else
            {
                saveChanges = DialogResult.No;
            }

            if (saveChanges == DialogResult.Yes)
            {
                if (m_strFile == "")
                {
                    SaveAs();
                }
                else
                {
                    writeTodoListFile();
                }
            }
            OpenFileDialog ofdTodoList = new OpenFileDialog();

            ofdTodoList.InitialDirectory = "" + System.IO.Path.DirectorySeparatorChar;
            ofdTodoList.Filter = "Todolist files (*.xml,*.tdl)|*.xml,*.tdl|All files (*.*)|*.*";
            ofdTodoList.FilterIndex = 1;

            if (ofdTodoList.ShowDialog() == DialogResult.OK)
            {
                pi_clearData();
                LoadingData = true;
                m_strFile = ofdTodoList.FileName;
                SetPref("LastOpenedFile", m_strFile);
                DataChanged = false;
                FillTree();
                LoadingData = false;
            }
            DataChanged = false;
        }
        #endregion
        #region Task
        private void AddTask()
        {
            CTask tmpTask = new CTask();
            tmpTask.TaskId = m_iNextUniqueID++;
            tmpTask.Title = M_NEW_TASK_NAME;

            TodoListTreeNode newNode = new TodoListTreeNode(M_NEW_TASK_NAME);
            newNode.Task = tmpTask;
            newNode.TaskId = tmpTask.TaskId;
            DataChanged = true;
            if (m_SelectedTreeNode == null)
            {
                oTVTodoList.Nodes.Add(newNode);

            }
            else if (m_SelectedTreeNode.Parent == null)
            {
                oTVTodoList.Nodes.Add(newNode);
            }
            else
            {
                m_SelectedTreeNode.Parent.Nodes.Add(newNode);
            }
            oTVTodoList.SelectedNode = newNode;
            txtTaskName.Visible = true;
            dtDueDate.Visible = true;
            txtTaskName.Focus();
            txtTaskName.SelectAll();
        }
        private void AddSubTask()
        {
            CTask tmpTask = new CTask();
            tmpTask.TaskId = m_iNextUniqueID++;
            tmpTask.Title = M_NEW_TASK_NAME;

            TodoListTreeNode newNode = new TodoListTreeNode(M_NEW_TASK_NAME);
            newNode.Task = tmpTask;
            newNode.TaskId = tmpTask.TaskId;
            DataChanged = true;

            if (m_SelectedTreeNode != null)
            {
                m_SelectedTreeNode.Nodes.Add(newNode);
            }
            oTVTodoList.SelectedNode = newNode;
            txtTaskName.Visible = true;
            dtDueDate.Visible = true;
            txtTaskName.Focus();
            txtTaskName.SelectAll();
        }
        private void DeleteTask()
        {
            DialogResult DeleteTask = DialogResult.Yes;

            //ask to lose changes???
            DeleteTask = MessageBox.Show("Are You Sure?", "Delete?", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);

            if (DeleteTask == DialogResult.Yes)
            {
                m_SelectedTreeNode.Remove();
            }
        }
        #endregion
        //TODO: Change iLevel to Enum
        private void SetFilter(Int16 iLevel)
        {
            mnuViewAll.Checked = false;
            mnuViewActive.Checked = false;
            mnuViewComplete.Checked = false;

            if (iLevel == 0)
            {
                mnuViewAll.Checked = true;
            }
            else if (iLevel == 1)
            {
                mnuViewActive.Checked = true;
            }
            else if (iLevel == 2)
            {
                mnuViewComplete.Checked = true;
            }

            m_iLevel = iLevel;

            LoadXMLDOM();
        }
        #endregion

        #region Button Menu Events
        private void bMenu_Click(object sender, EventArgs e)
        {
            if(bMenu.Text != "CLOSE")
            {
                bMenu.Text = "CLOSE";
                bMenu4.Visible = true;
                bMenu8.Visible = true;
                bMenu12.Visible = true;
                bMenu13.Visible = true;
                bMenu14.Visible = true;
                bMenu15.Visible = true;
            }
            else
            {
                HidebMenu();
            }
        }
        #region Sub Menu Buttons
        private void bMenu4_Click(object sender, EventArgs e)
        {
            HidebMenuMiddle();
            HidebMenuBottom();
            if (bMenu1.Visible == false)
            {
                bMenu1.Visible = true;
                bMenu2.Visible = true;
                bMenu3.Visible = true;
            }
            else
            {
                HidebMenuTop();
            }
        }
        private void bMenu8_Click(object sender, EventArgs e)
        {
            HidebMenuTop();
            HidebMenuBottom();
            if (bMenu5.Visible == false)
            {
                bMenu5.Visible = true;
                bMenu6.Visible = true;
                bMenu7.Visible = true;
            }
            else
            {
                HidebMenuMiddle();
            }

        }
        private void bMenu12_Click(object sender, EventArgs e)
        {
            HidebMenuTop();
            HidebMenuMiddle();
            if (bMenu9.Visible == false)
            {
                bMenu9.Visible = true;
                bMenu10.Visible = true;
                bMenu11.Visible = true;
            }
            else
            {
                HidebMenuBottom();
            }

        }
        #endregion
        #region Action Menu Buttons
        private void bMenu7_Click(object sender, EventArgs e)
        {
            FrmPreferences ofrmPreferences = new FrmPreferences();
            ofrmPreferences.Closed += new EventHandler(PreferencesClosed);
            ofrmPreferences.ShowDialog();
        }
        private void bMenu11_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.Cursor.Current = Cursors.WaitCursor;
            HidebMenu();
            SetFilter(1);
            System.Windows.Forms.Cursor.Current = Cursors.Default;
        }
        private void bMenu10_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.Cursor.Current = Cursors.WaitCursor;
            HidebMenu();
            SetFilter(2);
            System.Windows.Forms.Cursor.Current = Cursors.Default;
        }
        private void bMenu9_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.Cursor.Current = Cursors.WaitCursor;
            HidebMenu();
            SetFilter(0);
            System.Windows.Forms.Cursor.Current = Cursors.Default;
        }
        private void bMenu1_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.Cursor.Current = Cursors.WaitCursor;
            HidebMenu();
            NewFile();
            System.Windows.Forms.Cursor.Current = Cursors.Default;
        } 
        private void bMenu2_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.Cursor.Current = Cursors.WaitCursor;
            HidebMenu();
            OpenFile();
            System.Windows.Forms.Cursor.Current = Cursors.Default;
        }        
        private void bMenu3_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.Cursor.Current = Cursors.WaitCursor;
            HidebMenu();
            SaveFile();
            System.Windows.Forms.Cursor.Current = Cursors.Default;
        }
        #endregion
        #region Task Menu Buttons
        private void bMenu13_Click(object sender, EventArgs e)
        {
            DeleteTask();
            HidebMenu();
        }

        private void bMenu14_Click(object sender, EventArgs e)
        {
            AddSubTask();
            HidebMenu();
        }

        private void bMenu15_Click(object sender, EventArgs e)
        {
            AddTask();
            HidebMenu();
        }


        #endregion
        #endregion
        #region Button Menu Methods
        private void DisablebMenu()
        {
            bMenu.Visible = false;
            HidebMenu();
        }
        private void HidebMenu()
        {
            bMenu.Text = "MENU";
            bMenu1.Visible = false;
            bMenu2.Visible = false;
            bMenu3.Visible = false;
            bMenu4.Visible = false;
            bMenu5.Visible = false;
            bMenu6.Visible = false;
            bMenu7.Visible = false;
            bMenu8.Visible = false;
            bMenu9.Visible = false;
            bMenu10.Visible = false;
            bMenu11.Visible = false;
            bMenu12.Visible = false;
            bMenu13.Visible = false;
            bMenu14.Visible = false;
            bMenu15.Visible = false;
        }
        private void HidebMenuTop()
        {

            bMenu1.Visible = false;
            bMenu2.Visible = false;
            bMenu3.Visible = false;
        }
        private void HidebMenuMiddle()
        {
            bMenu5.Visible = false;
            bMenu6.Visible = false;
            bMenu7.Visible = false;
        }
        private void HidebMenuBottom()
        {
            bMenu9.Visible = false;
            bMenu10.Visible = false;
            bMenu11.Visible = false;
        }
        #endregion

        private void frmMain_KeyDown(object sender, KeyEventArgs e)
        {
            if ((e.KeyCode == System.Windows.Forms.Keys.Up))
            {
                // Up
            }
            if ((e.KeyCode == System.Windows.Forms.Keys.Down))
            {
                // Down
            }
            if ((e.KeyCode == System.Windows.Forms.Keys.Left))
            {
                // Left
            }
            if ((e.KeyCode == System.Windows.Forms.Keys.Right))
            {
                // Right
            }
            if ((e.KeyCode == System.Windows.Forms.Keys.Enter))
            {
                // Enter
                //if selected tab is treeview
                if(tabCtrlMain.SelectedIndex == 0)
                {
                    if (m_SelectedTreeNode != null)
                    { 
                        m_SelectedTreeNode.Checked = !m_SelectedTreeNode.Checked;
                    }
                    if (m_selectedTask != null)
                    {
                        m_selectedTask.Complete = !m_selectedTask.Complete;
                    }
                }
            }

        }

        private void loadDueTasks()
        {
            DataTable dtDueTasks = new DataTable();
            dtDueTasks.Columns.Add("Name");
            dtDueTasks.Columns.Add("DueDate");

            foreach (CTask oCTask in lstAllTasks)
            {
                if (oCTask.DueDate != new DateTime())
                {
                    if (oCTask.DueDate <= DateTime.Now)
                    {
                        DataRow drTask = dtDueTasks.NewRow();
                        drTask["Name"] = oCTask.Title;
                        drTask["DueDate"] = oCTask.DueDate;
                        dtDueTasks.Rows.Add(drTask);
                    }
                }
            }
            dgDueTasks.DataSource = dtDueTasks;
        }

        private void dtpStartDate_ValueChanged(object sender, EventArgs e)
        {
            m_selectedTask.StartDate = dtpStartDate.Value;
        }

        private void dtpDueDate_ValueChanged(object sender, EventArgs e)
        {
            m_selectedTask.DueDate = dtpDueDate.Value;
        }

        private void dtpCompletedDate_ValueChanged(object sender, EventArgs e)
        {
            m_selectedTask.DoneDate = dtpDueDate.Value;
        }
        private void tabChanged(object sender, EventArgs e)
        {

            switch (tabCtrlMain.SelectedIndex)
            {
                case 0:
                    
                    break;
                case 1:
                    
                    break;
                case 2:
                    loadDueTasks();
                    break;
                case 3:
                    
                    break;
            }
        }

        private void menuItem15_Click(object sender, EventArgs e)
        {
            LoadXMLDOM();
        }

        private void LoadXMLDOM()
        {
            xmlDoc = new XmlDocument();
            xmlDoc.Load(m_strFile);
            XmlNode oNode = xmlDoc.DocumentElement;
            
            oTVTodoList.Nodes.Clear();
            LoadNode(oTVTodoList, oNode, null);
        }

        private void LoadNode(TreeView oTreeView, XmlNode oNode, TreeNode oTreeNode)
        {
            
            foreach (XmlNode childnode in oNode.ChildNodes)
            {
                if (childnode.Attributes[Todo.PercentComplete] != null)
                {
                    bool bAddNode = false;
                    if (m_iLevel == 0)
                    {
                        bAddNode = true;
                    }
                    else if (m_iLevel == 1 && childnode.Attributes[Todo.PercentComplete].Value != "100")
                    {
                        bAddNode = true;
                    }
                    if(bAddNode)
                    {
                        AddNodeToTree(childnode, oTreeNode, oTreeView);
                    }
                }
            }
        }

        private void AddNodeToTree(XmlNode childnode, TreeNode oTreeNode, TreeView oTreeView)
        {
            if (childnode.Attributes[Todo.Title] != null)
            {
                TreeNode childTreeNode = new TreeNode(childnode.Attributes[Todo.Title].Value);
                if (oTreeNode != null)
                {
                    ConfigureTreeNode(childnode, childTreeNode);
                    oTreeNode.Nodes.Add(childTreeNode);
                }
                else
                {
                    ConfigureTreeNode(childnode, childTreeNode);
                    oTreeView.Nodes.Add(childTreeNode);
                }
                LoadNode(oTreeView, childnode, childTreeNode);
            }
        }

        private void ConfigureTreeNode(XmlNode childnode, TreeNode childTreeNode)
        {
            childTreeNode.Tag = childnode;
            if(childnode.Attributes[Todo.PercentComplete].Value == "100")
            {
                childTreeNode.Checked = true;
            }
        }

        private void menuItem16_Click(object sender, EventArgs e)
        {
            if (oTVTodoList.SelectedNode != null)
            {
                XmlNode oNode = (XmlNode)oTVTodoList.SelectedNode.Tag;
                oTVTodoList.Nodes.Clear();
                LoadNode(oTVTodoList, oNode, null);
            }
        }

        private void menuItem17_Click(object sender, EventArgs e)
        {
            oTVTodoList.Nodes.Clear();
            LoadNode(oTVTodoList, xmlDoc.DocumentElement, null);
        }

        private void menuItem18_Click(object sender, EventArgs e)
        {
            
            XmlNode oNode = (XmlNode)oTVTodoList.Nodes[0].Tag;
            XmlNode oParentNode = oNode.ParentNode.Clone();
            oTVTodoList.Nodes.Clear();
            LoadNode(oTVTodoList, oParentNode.ParentNode, null);
            
        }
    }
}